#include "reggen.h"
#include "..\utilcvt.h"

unsigned short CheckSum(char *buf, unsigned long len)
{
	unsigned short sum = 0;
	unsigned long i;

	for(i=0; i<len; i++)
		sum ^= (unsigned char)buf[i]<<((i&0x01)*8);
	return sum;
}

DWORD CheckSum2(char *buf, unsigned long len)
{
	unsigned short sum1 = 23870, sum2=0x5a5a;
	short m1=23893;
	unsigned i;

	for(i=0; i<len; i++)
	{
		sum1 += m1*buf[i]*(i+1);
		sum2 += buf[i]^sum1;
	}
	return sum1 | ((long) sum2<<16);
}

int Scramble(unsigned long skey, char *sdata, void *data, unsigned long len)
{
	char buf[_MAX_PATH];
	unsigned long code = 0;
	unsigned long bitn = 0;
	unsigned long i, j = 0, k;

	if(len==0)
	{
		sdata[0] = '\0';
		return 0;
	}
	k = skey%len;
	for(i=0; i<len; i++)
		buf[i] = (char)(((char *)data)[(i+k)%len]^(skey*i));
	for(i=0; i<len; i++)
	{
		code <<= 8;
		code |= buf[i]&0xff;
		bitn += 8;
		while(bitn>=5)
		{
			bitn -= 5;
			k = (code>>bitn)&0x1f;
			sdata[j++] = (char)(k<10 ? k+'0' : k+('A'-10));
		}
	}
	if(bitn)
	{
		k = (code<<(5-bitn))&0x1f;
		sdata[j++] = (char)(k<10 ? k+'0' : k+('A'-10));
	}
	sdata[j] = '\0';

	return 0;
}

void GenerateKey( LONGLONG llBase, DWORD dwKey, DWORD dwProductId, char* szReturn )
{
	if ( szReturn==NULL ) 
	{
		szReturn = new char[_MAX_PATH];
	}

	char buf[_MAX_PATH];
	unsigned long sum;
	ZeroMemory(buf, _MAX_PATH);
	short iProduct = dwProductId;
	memcpy(buf, &iProduct, 2);
	memcpy(buf+6,&llBase,8);
	sum = CheckSum2(buf,14);	
	CUTILcvt::LittleEndian((unsigned long *)(buf+14), &sum);
	Scramble(dwKey,szReturn,buf,18);

}


int InfoToText(char *szKey, DWORD dwKey, DWORD productID, char *buf)
{
	Scramble(productID,buf,&dwKey,sizeof(unsigned long));
	strcat(buf,szKey);
	return 0;
}
